package com.reportingapplication.teacher;

import java.util.ArrayList;
//import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.reportingapplication.teacher.tools.JSONParser;
import com.reportingapplication.teacher.tools.ID;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Vibrator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Notification.Builder;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	/** The messageboard where all information is displayed **/
	private TextView messageBoard;
	/** The button which is used to report **/
	private Button reportButton;
	/** Name of victim */
	private String student;
	/** Where all information is saved **/
	private SharedPreferences settings;
	/** Google variable **/
	private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    /** The amount of time it took to handle the request **/
//    private String end_time;
	/** boolean indicating whether the App is in the for- or background **/
	private static boolean isInForeground;
    
	public static MainActivity activity = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		activity = this;
		setContentView(R.layout.activity_main);
		// Get the settings for this App.
		settings = getSharedPreferences(ID.PREFS_NAME, 0);
		//Check if the user is registered.
		boolean loggedIn = settings.getBoolean(ID.LOGGED_IN, false);
		if(!loggedIn){
			// User is not registered so go to the activity to do so.
			Intent intent = new Intent(this, SignupActivity.class);
			startActivity(intent);
		}
		// Setup the local variables.
		messageBoard = (TextView) findViewById(R.id.messageBoard);
		reportButton = (Button) findViewById(R.id.reportButton);
		messageBoard.setText("Op dit moment is er nog niks te doen.");
		reportButton.setEnabled(false);
		reportButton.setVisibility(View.INVISIBLE);
		isInForeground = true;
		Intent i = getIntent();
		if(i.getStringExtra(ID.BROADCAST_RECEIVER) != null && i.getStringExtra(ID.BROADCAST_RECEIVER).equals(ID.BROADCAST_RECEIVER)){
			doThis(i);
		}
	}
	
	public void doThis(Intent intent){
		String type = intent.getStringExtra(ID.TYPE);
		if (type.equals(ID.NOTIFICATION)) {
			// Get the location to report from the message.
			String location = intent.getStringExtra(ID.LOCATION);
			student = intent.getStringExtra("student");
			// Get the event_id of the report.
			settings.edit().putBoolean("isCalled", true)
					.putString(ID.LOCATION, location)
					.putString("student", student)
					.putString(ID.TYPE, ID.NOTIFICATION)
					.commit();
			// Finish handling the notification.
			MainActivity.this.finishNotification("Kun je naar "+location+" gaan? "+student+" wacht daar. Druk daarna op de knop.");
		} else if (type.equals(ID.FINISHED)) {
			settings.edit()
			.putBoolean("isCalled", false)
			.putString(ID.TYPE, ID.FINISHED)
			.commit();
			// Finish handling the notification.
			MainActivity.this.finishNotification("Er is al een docent aanwezig. Je hoeft verder niks te doen.");
		}
	}
	
	/**
	 * Standard.
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	/** 
	 * Called when the device resumes from sleep
	 */
	@Override
    protected void onResume() {
		super.onResume();
		// The app is in the foreground now.
		isInForeground = true;
        // Check device for Play Services APK.
        checkPlayServices();
    }
	
	/**
	 * Called when the device goes to sleep
	 */
	@Override
	protected void onPause(){
		super.onPause();
		// Set that the app is in the background.
		isInForeground = false;
	}
	    
	/**
	 * Called when a button is pressed
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
	    if(keyCode == KeyEvent.KEYCODE_BACK)
	    {
	    	// If the back key is pressed, set the task in the background, so GCM messages can still be received.
	    	moveTaskToBack(true);
	    	return true;
	    }
	    return super.onKeyDown(keyCode, event);
	}
	
	/**
	 * Reset screen when orientation is changed
	 */
	@Override
	public void onConfigurationChanged(Configuration config){
		super.onConfigurationChanged(config);
		setContentView(R.layout.activity_main);
		// Setup the local variables.
		settings = getSharedPreferences(ID.PREFS_NAME, 0);
		messageBoard = (TextView) findViewById(R.id.messageBoard);
		reportButton = (Button) findViewById(R.id.reportButton);
		messageBoard.setText("Op dit moment is er nog niks te doen.");
		isInForeground = true;
		String location = settings.getString(ID.LOCATION, ID.EMPTY);
		//If the notification has been made, keep showing it, no matter the rotation
		if(settings.getBoolean("isCalled", false)){
			// Set a message to press the button and where to do so.
    		messageBoard.setText("Kun je naar "+location+" gaan? "+student+" wacht daar. Druk daarna op de knop.");
    		reportButton.setEnabled(true);
    		reportButton.setVisibility(View.VISIBLE);
		}else{
			reportButton.setEnabled(false);
			reportButton.setVisibility(View.INVISIBLE);
		}
	}
	
	/**
     * Check the device to make sure it has the Google Play Services APK. If
     * it doesn't, display a dialog that allows users to download the APK from
     * the Google Play Store or enable it in the device's system settings.
     */
    private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.e(ID.ERROR, "This device is not supported.");
                finish();
            }
            return false;
        }
        return true;
    }
    
    /**
     * Called when the button is pressed
     */
    public void handlePress(View view) {
    	// Calculate the time it took to handle the request.
    	settings.edit()
		.putBoolean("isCalled", false)
		.commit();
    	(new NotificationTask()).execute();
    	// Reset everything.
    	messageBoard = (TextView) findViewById(R.id.messageBoard);
		reportButton = (Button) findViewById(R.id.reportButton);
		messageBoard.setText("Op dit moment is er nog niks te doen.");
		reportButton.setEnabled(false);
		reportButton.setVisibility(View.INVISIBLE);
    }
    
    /**
     * Finish a notification process. This is called when the device receives a notification that 
     * the button was pressed by a student.
     */
	@SuppressLint("NewApi")
	public void finishNotification(final String message){			
		// Prepare intent which is triggered
    	Intent intent = new Intent(this, MainActivity.class);
    	PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
    	
    	if(!isInForeground){
    		// Build notification which is displayed on the notification bar.
    		// This is only done when the app is in the background.
        	// The addAction re-uses the same intent.
        	Builder n  = new Notification.Builder(this)
        	        .setContentTitle("Nieuw bericht")
        	        .setContentText(message)
        	        .setSmallIcon(R.drawable.ic_launcher)
        	        .setContentIntent(pIntent)
        	        .setAutoCancel(true);
        	NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        	notificationManager.notify(0, n.build());
    	}
    	// Set a message on the message board. This must be done in the main thread.
    	runOnUiThread(new Runnable() {
            @Override
			public void run() {
            	if(settings.getString(ID.TYPE, ID.EMPTY).equals(ID.NOTIFICATION)){
            		// Get hold of the phone vibrator
                	Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            		// Set the vibration pattern
                	// This example will cause the phone to vibrate "SOS" in Morse Code
                	// Length of a Morse Code "dot" in milliseconds
                	int dot = 200;
                	// Length of a Morse Code "dash" in milliseconds
                	int dash = 500;
                	// Length of Gap Between dots/dashes
                	int short_gap = 200;    
                	// Length of Gap Between Letters
                	int medium_gap = 500;
                	// Length of Gap Between Words
                	int long_gap = 1000;
                	long[] pattern = {
                	    0,  // Start immediately
                	    dot, short_gap, dot, short_gap, dot,    // s
                	    medium_gap,
                	    dash, short_gap, dash, short_gap, dash, // o
                	    medium_gap,
                	    dot, short_gap, dot, short_gap, dot,    // s
                	    long_gap
                	};
                	// Vibrate
                	v.vibrate(pattern, -1);
            		// Set a message to press the button and where to do so.
            		messageBoard.setText(message);
            		reportButton.setEnabled(true);
            		reportButton.setVisibility(View.VISIBLE);
            	}else if (settings.getString(ID.TYPE, ID.EMPTY).equals(ID.FINISHED)){
            		// Get hold of the phone vibrator
                	Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
                	// Set the vibration pattern 
                	int vibration = 1000;
                	int pause = 500;
                	long[] pattern = {0, vibration, pause, vibration};
                	// Vibrate
                	v.vibrate(pattern, -1);
            		messageBoard.setText(message);
            		reportButton.setEnabled(false);
            		reportButton.setVisibility(View.INVISIBLE);
        	    	startTimer();
            	}
            	
            }
        });
    }
	
	public void startTimer(){
		new Timer().schedule(new TimerTask() {
		    @Override
		    public void run() {
		    	runOnUiThread(new Runnable() {
		    		@Override
		    		public void run() {
		    			messageBoard.setText("Op dit moment is er nog niks te doen.");
		    		}
		    	});
		    }
		}, 1000*60*2);
	}
	    
	/**
     * Called when the teacher pressed the button and all teachers need to receive a notification.
     */
	private class NotificationTask extends AsyncTask<String, String, String>{
		@Override
		protected String doInBackground(String... args) {	    	
			// Create a list with the values to be sent to the database.
	    	List<NameValuePair> params = new ArrayList<NameValuePair>();
	        params.add(new BasicNameValuePair(ID.NAME, settings.getString(ID.NAME, ID.EMPTY)));
	        boolean successful = false;
	        int tries = 0;
	        while(!successful){
	        	// Create request and send it.
		        JSONParser jParser = new JSONParser();
		        JSONObject json = jParser.makeHttpRequest(ID.URL_CANCEL_TEACHERS, ID.POST_REQUEST, params);  
		        int success;
				try {
					success = json.getInt("failure");
					if (success != 0) {
						Log.i(ID.INFO, "Unsuccessful, retrying after random sleep time");
						tries++;
						if(tries == 5){
							Log.e(ID.ERROR, "Fail in MainActivity:265");
							return null;
						}
						Thread.sleep((long) Math.random()*1000*tries);
					}else{
						successful = true;
					}
				} catch (JSONException e) {
					Log.e(ID.ERROR, e.getMessage());
				} catch (InterruptedException e) {
					Log.e(ID.ERROR, e.getMessage());
				}
	        }
	    	// Reset all values and wait until the next message comes in
	        student = "";
			return null;
		}
	}
}